// https://learn.microsoft.com/en-us/typography/opentype/spec/name
use super::*;

#[derive(Clone)]
pub struct Table<'a> {
	pub version: u16,
	pub count: u16,                               // Number of name records.
	pub storage_offset: Offset16,                 // Offset to start of string storage (from start of table).
	pub name_record: LazyArray16<'a, NameRecord>, //The name records where count is the number of records.
	// version 1
	// pub lang_tag_count: u16, // Number of language-tag records.
	pub lang_tag_record: LazyArray16<'a, LangTagRecord>, // The language-tag records where langTagCount is the number of records.
	//
	pub data: &'a [u8],
}
impl<'a> Table<'a> {
	pub fn parse(data: &'a [u8]) -> Option<Self> {
		let mut s = Stream::new(data);
		let version = s.read()?;
		let count = s.read()?;
		let storage_offset = s.read()?;
		let name_record = s.read_array16::<NameRecord>(count)?;
		let lang_tag_record = match version {
			0 => s.read_array16::<LangTagRecord>(0)?,
			1 => s.parse_array16::<LangTagRecord>()?,
			_ => return None,
		};
		Some(Self {
			version,
			count,
			storage_offset,
			name_record,
			lang_tag_record,
			data,
		})
	}
}
impl<'a> core::fmt::Debug for Table<'a> {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		f.debug_struct("Table")
			.field("version", &self.version)
			.field("count", &self.count)
			.field("storage_offset", &self.storage_offset)
			.field("name_record", &self.name_record.len())
			.field("lang_tag_record", &self.lang_tag_record.len())
			// .field("data", &self.data)
			.finish()
	}
}

#[derive(Debug, Clone, Copy)]
pub struct NameRecord {
	pub platform_id: u16,        // Platform ID.
	pub encoding_id: u16,        // Platform-specific encoding ID.
	pub language_id: u16,        // Language ID.
	pub name_id: u16,            // Name ID.
	pub length: u16,             // String length (in bytes).
	pub string_offset: Offset16, // String offset from start of storage area (in bytes).
}
impl FromData for NameRecord {
	const SIZE: usize = 12;
	#[inline]
	fn parse(data: &[u8]) -> Option<Self> {
		let mut s = Stream::new(data);
		let this = Self {
			platform_id: s.read()?,
			encoding_id: s.read()?,
			language_id: s.read()?,
			name_id: s.read()?,
			length: s.read()?,
			string_offset: s.read()?,
		};
		_ = PlatformEncoding::new(this.platform_id, this.encoding_id)?;
		Some(this)
	}
}
#[derive(Debug, Clone, Copy)]
pub struct LangTagRecord {
	pub length: u16,               // Language-tag string length (in bytes).
	pub lang_tag_offset: Offset16, // Language-tag string offset from start of storage area (in bytes).
}
impl FromData for LangTagRecord {
	const SIZE: usize = 4;
	#[inline]
	fn parse(data: &[u8]) -> Option<Self> {
		let mut s = Stream::new(data);
		Some(LangTagRecord {
			length: s.read()?,
			lang_tag_offset: s.read()?,
		})
	}
}
